<?php
namespace app\common\model;
// 订单 处理业务

use plug\SUtil;
use think\Db;
use wxzhifu\example\JsApiPay;
use wxzhifu\example\WxPayConfig;
use wxzhifu\lib\WxPayApi;
use wxzhifu\lib\WxPayUnifiedOrder;

class Reserveorder extends Base
{
    // 设置当前模型对应的完整数据表名称
    protected $table = 'ddt_reserve_order';
    // 主键ID
    protected $pk = 'r_o_id';

    //订单状态
    public static $statelist = [
        '1'=>'待支付',
        '2'=>'已支付',
        '3'=>'已完成',
        '4'=>'用户取消订单',
        '5'=>'订单退款',
    ];
    //支付状态
    public static $paystatelist = [
        '1' => '待支付',
        '2' => '已支付',
        '3' => '已取消',
    ];
    //性别类型
    public static $sexlist = [
        '1' => '先生',
        '2' => '女士',
    ];

    /**
     * @param array $where  // 查询的条件
     * @param string $item  // 查询的参数
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    function getOne($where=[1], $item='*')
    {
        $rs = $this
            ->field($item)
            ->where($where)
            ->find();

        return $rs;
    }

    function getJoinOrder($where=[1], $item='*',$join = [['ddt_shops s','o.shop_id = s.shop_id']])
    {
        $rs = $this
            ->alias('o')
            ->join($join)
            ->field($item)
            ->where($where)
            ->find();

        return $rs;
    }

    function getJoinOrderList($cond, $item='o.*',$join = [['ddt_shops s','o.shop_id = s.shop_id']])
    {
        $where = null;

        if(!empty($cond['payments_id'])){
            $where[] = ['o.payments_id', '=',$cond['payments_id']];
        }

        $rs = $this
            ->alias('o')
            ->leftJoin($join)
            ->field($item)
            ->where($where)
            ->select();

        return $rs;
    }

    function get_list($cond, $orderby, $item)
    {

        $where = null;

        if(!empty($cond['user_id'])){
            $where[] = ['user_id','=', $cond['user_id']];
        }
        if(!empty($cond['payment_id'])){
            $where[] = ['payments_id','=', $cond['payment_id']];
        }

        if(!empty($cond['type'])){
            $where[] = ['type', '=', $cond['type']];
        }

        if(!empty($cond['shopid'])){
            $where[] = ['shopid', '=', $cond['shopid']];
        }

        if(!empty($cond['state'])){
            $where[] = ['state', '=', $cond['state']];
        }

        $rs = Db::table($this->table)
            ->field($item)
            ->where($where)
            ->order($orderby)
            ->select();
        return $rs;
    }

    //  接口获取订单详情
    function api_order_details($orderId,$item = 'od.*',$join = [['ddt_agent_order o','od.r_o_id = o.r_o_id'],['ddt_shops s','o.shop_id = s.shop_id']])
    {
        $detailModel = new AgentOrderDetail();
        $rs = $detailModel
            ->alias('od')
            ->leftJoin($join)
            ->field($item)
            ->where('od.r_o_id',$orderId)
            ->select()->toArray();
        return $rs;
    }

    /**
     * @param array $userinfo  // 用户信息
     * @param array $shopinfo  // 店铺信息
     * @param array $data // 价格信息
     * @param array $submit // 提交信息
     * @return array
     */
//    处理订座订单插入数据
    function placereserveorder($userinfo,$shopinfo,$data,$submit){
        $time = time();
        $result = [
            'code' => false,
            'data' => [],
        ];
//        var_dump($user);die;
        $paydata = [
            'coupon_amount' => $data['payinfo']['allcoupon_amount'],
            'order_amount' => $data['payinfo']['allorder_amount'],
            'pay_amount' => $data['payinfo']['pay_amount'],
        ];
        $insertorder['data'] = $paydata;
        $insertorder['submit'] = $submit;
        $insertorder['shop_id'] = $shopinfo['shop_id'];
        $insertorder['order_time'] = $time;
        $insertorder['user_id'] = $userinfo['user_id'];
        $insertorder['receive_id'] = 0;
        $insertorder['access_code'] = SUtil::random(8,1);;

        $payments_id = 0;
        $this->startTrans();
        if($data['payinfo']['pay_amount'] > 0){ // 是否需要走支付流程，靠$payments_id
            $paymentModel = new Payments();
            $insertpayments = [
                "user" => $userinfo,
                "data" => $data['payinfo'],
            ];
            $payments_id = $paymentModel->insertpayments($insertpayments,"reserve");
            if($payments_id === false){
                $paymentModel->rollback();
                $this->setError(-1,'插入购买记录失败');
                return $result;
            }
            $insertorder['payments_id'] = $payments_id;
        } else {
            $insertorder['order_status'] = 2;
            $insertorder['pay_status'] = 2;
            $insertorder['payments_id'] = $payments_id;
            $insertorder['pay_time'] = $time;
        }
        $orderid = $this->insertorder($insertorder);
        if($orderid === false){
            $this->rollback();
            $this->setError(-1,'订单生成失败');
            return $result;
        }

        $this->commit();
        $result['code'] = true;
        $result['data'] = [
            'orderid' => $orderid,
            'paymentsid' => $payments_id,
        ];
        return $result;
    }

//    订单插入操作
    function insertorder($insertdata){
        if(!isset($insertdata['order_time'])){
            $insertdata['order_time'] = time();
        }
        $orderno = "ro".date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);;
        $data = [
            'shop_id' => $insertdata['shop_id'],
            'receive_id' => $insertdata['receive_id'],
            'coupon_amount' => $insertdata['data']['coupon_amount'],
            'order_amount' => $insertdata['data']['order_amount'],
            'pay_amount' => $insertdata['data']['pay_amount'],
            'order_time' => $insertdata['order_time'],
            'orderno' => $orderno,
            'user_id' => $insertdata['user_id'],
            'payments_id' => $insertdata['payments_id'],
            'reserve_uname' => $insertdata['submit']['reserve_uname'],
            'sex' => $insertdata['submit']['sex'],
            'reserve_uphone' => $insertdata['submit']['reserve_uphone'],
            'remarks' => $insertdata['submit']['remark'],
            'place_time' => $insertdata['submit']['place_time'],
            'persons' => $insertdata['submit']['persons'],
            'access_code' => $insertdata['access_code'],
        ];
        if(isset($insertdata['order_status'])){
            $data['order_status'] = $insertdata['order_status'];
        }
        if(isset($insertdata['pay_status'])){
            $data['pay_status'] = $insertdata['pay_status'];
        }
        if(isset($insertdata['pay_time'])){
            $data['pay_time'] = $insertdata['pay_time'];
        }
        $rs = $this->save($data);
        if ($rs === false) {
            return false;
        }
        $orderid = $this->r_o_id;
        return $orderid;
    }

//    插入预约记录操作
    function insertrecord($insertdata){
        $data = [
            'shop_id' => $insertdata['shop_id'],
            'order_id' => $insertdata['order_id'],
            'user_id' => $insertdata['user_id'],
            'reserve_uname' => $insertdata['reserve_uname'],
            'sex' => $insertdata['sex'],
            'reserve_uphone' => $insertdata['reserve_uphone'],
            'remarks' => $insertdata['remark'],
            'place_time' => $insertdata['place_time'],
            'persons' => $insertdata['persons'],
            'add_time' => time(),
        ];
        $rs = $this->save($data);
        if ($rs === false) {
            return false;
        }
        $orderid = $this->r_o_id;
        return $orderid;
    }

//    订单微信支付
    function wxpay($user,$paymentsid,$wxconfig,$notifyurl,$pay_end = 1,$tradetype = "JSAPI")
    {
//        $key = md5(Config::get('token.key'));

//        $attach = JWTUtil::encode(implode(',',$orderids),$key);
//        var_dump($attach);die;
        $paymentsModel = new Payments();
        $where = [
            'payments_id' => $paymentsid
        ];
        $payments = $paymentsModel->where($where)->find();
        if($pay_end == 1){// 下单端不同参数不同 1-h5下单支付 2-小程序下单支付
            $openId = $user['wx_openid'];
            $attch['pay_end'] = '1';
        } else {
            $openId = $user['applets_openid'];
            $attch['pay_end'] = '2';
        }
        $attch = json_encode($attch,true);
        $notifyurl = request()->domain().$notifyurl;
        $input = new WxPayUnifiedOrder();
        $input->SetBody("paymentsid_".$paymentsid);
        $input->SetAttach($attch);
        $input->SetOut_trade_no($payments['order_nos']);
        $input->SetTotal_fee($payments['amount'] * 100);//订单金额以分为单位
//        $input->SetTotal_fee($order['totalfee'] * 100);//订单金额以分为单位
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 3600));
//        $input->SetGoods_tag("test");
        $input->SetNotify_url($notifyurl);
        $input->SetTrade_type($tradetype);
        $input->SetOpenid($openId);
//        var_dump($input);die;
        $config = new WxPayConfig();
        $config->appid = $wxconfig['AppID'];
        $config->secret = $wxconfig['AppSecret'];
        $config->mchid = $wxconfig['MchId'];
        $config->key = $wxconfig['MchKey'];
//        var_dump($config);die;
        $result = WxPayApi::unifiedOrder($config, $input);
//        print_r($result);die;
        if (!empty($result["return_code"]) && strcasecmp($result["return_code"], "fail") === 0) {
            $msg = empty($result["return_msg"]) ? "发生错误，下单失败" : $result["return_msg"];
            $this->setError(-1,$msg);
            return false;
        }
        $tools  = new JsApiPay();
        $json_string = $tools->GetJsApiParameters($result,$config);
        $results = json_decode($json_string, true);
        $results["prepay_id"] = $result["prepay_id"];
//        dump($results);die;
        return $results;
    }

    function get_order_column($cond,$column)
    {
        $where = [];
        if(!empty($cond['orderids'])){
            $where[] = ['order_id','in',$cond['orderids']];
        }
        $rs = $this->where($where)->column($column);
        return $rs;
    }

//    操作确认订单
    function operatesure($condition){
        $where[] = ['r_o_id','=',$condition['order_id']];

        if(!empty($condition['user_id'])){
            $where[] = ['user_id', '=', $condition['user_id']];
        }
        $order = $this->getOne($where);
        if(empty($order)){
            $this->setError(-1,'用户不存在该订单');
            return false;
        }
        $order = $order->toArray();
        if($order['order_status'] != 3 || $order['pay_status'] != 2){
            $this->setError(-1,'订单状态有误不允许操作');
            return false;
        }
        $param = [
            'order_status' => 4,
        ];
        $this->startTrans();
        $rs = $this->where("r_o_id",'=',$order['r_o_id'])->update($param);
        if($rs == false){
            $this->rollback();
            $this->setError(-1,'操作失败');
            return false;
        }
        if($order['order_type'] == 1){
            $result = $this->updateshopstock($order['r_o_id']);
            if($result == false){
                $this->rollback();
                return false;
            }
        }
        $this->commit();
        return true;
    }

//    操作删除订单
    function operatedelete($condition){
        $where[] = ['r_o_id','=',$condition['order_id']];

        if(!empty($condition['user_id'])){
            $where[] = ['user_id', '=', $condition['user_id']];
        }
        $order = $this->getOne($where);
        if(empty($order)){
            $this->setError(-1,'用户不存在该订单');
            return false;
        }
        $order = $order->toArray();
        if($order['order_status'] != 4 && $order['order_status'] != 5){
            $this->setError(-1,'订单状态有误不允许操作');
            return false;
        }
        $param = [
            'is_del' => 2,
        ];
        $rs = $this->where("r_o_id",'=',$order['r_o_id'])->update($param);
        if($rs === false){
            $this->setError(-1,'操作失败');
            return false;
        }
        return true;
    }

//    验证待支付订单商品和店铺(商品或者店铺下架则自动取消订单）
    function tobepaidordercheck($condition){
        $result = [
            "code" => -1,
            "msg" => '',
            "data" => [],
        ];
        $where[] = ['r_o_id','=',$condition['order_id']];

        if(!empty($condition['user_id'])){
            $where[] = ['user_id', '=', $condition['user_id']];
        }
        $order = $this->getOne($where);
        if(empty($order)){
            $result['msg'] = '用户不存在该订单';
            return $result;
        }
        $order = $order->toArray();
//        var_dump($order);die;
        if($order['order_status'] != 1 || $order['pay_status'] != 1){
            $result['msg'] = '订单状态有误不允许取消';
            return $result;
        }
        $item = 'od.*,s.shop_id,s.approved as s_approved,s.state as s_state,p.is_del as p_del,p.state as p_state,p.approved as p_approved,ps.is_del as ps_del';
        $join = [
            ['ddt_agent_order o','od.r_o_id = o.r_o_id'],
            ['ddt_shops s','o.shop_id = s.shop_id'],
            ['ddt_products p','od.product_id = p.product_id'],
            ['ddt_products_stock ps','od.p_s_id = ps.p_s_id'],
        ];
        $details = $this->api_order_details($order['r_o_id'],$item,$join);
        if(empty($details)){
            $result['msg'] = '订单商品数据有误';
            return $result;
        }
        $result['code'] = 1;
        $result['msg'] = '验证通过';
        $result['data'] = [
            'order' => $order,
            'details' => $details,
        ];
        if($details[0]['s_state'] != 1 || $details[0]['s_approved'] != 1){
            $result['code'] = 2;
            $result['msg'] = '该商铺已下架';
        }
        foreach($details as $value){
            if($value['ps_del'] != 1 || $value['p_del'] != 1 || $value['p_state'] != 1 || $value['p_approved'] != 2){
                $result['code'] = 2;
                $result['msg'] = '订单中部分商品已下架';
                break;
            }
        }
        return $result;
    }

    /**
     * @param $orderid  // 订单id
     */
//    经销商批发总部代销增加线上批发商品库存
    function updateshopstock($orderid){
        $details = $this
            ->alias('o')
            ->leftJoin('ddt_agent_orderdetail od','od.r_o_id = o.r_o_id')
            ->field('od.product_id,od.p_s_id,od.quantity,o.user_id')
            ->where('o.r_o_id','=',$orderid)
            ->select()->toArray();
//        var_dump($details);die;
        $time = time();
        $insertdata = '';
        foreach($details as $value){
            $insertdata .= ",({$value['user_id']},{$value['product_id']},{$value['p_s_id']},{$value['quantity']},{$time})";
        }
        $sql = 'INSERT INTO `ddt_shops_stock`(`shop_id`, `product_id`,  `p_s_id`, `stock`, `update_time`) VALUES '
            .trim($insertdata,',').
            ' ON DUPLICATE KEY UPDATE `stock`= VALUES(stock) + stock,`update_time`= VALUES(update_time)';
//        var_dump($sql);die;
        $rs = $this->execute($sql);
        if(!$rs){
            $this->setError(-1,$this->getError());
            return false;
        }
        return true;
    }

//    获取预定订单列表
    function GetReserveOrderList($cond,$item = '*',$limit = 10){

        if(!empty($cond['user_id'])){
            $where[] = ['user_id','=', $cond['user_id']];
        }
        if(isset($cond['shop_id'])){
            $where[] = ['shop_id','=', $cond['shop_id']];
        }
        if(!empty($cond['order_type'])){
            $where[] = ['order_type', 'in', $cond['order_type']];
        }
        if(!empty($cond['status'])){
            $where[] = ['order_status', '=', $cond['status']];
        }
        if(!empty($cond['pay_status'])){
            $where[] = ['pay_status', '=', $cond['pay_status']];
        }
        if(!empty($cond['time'])){
            $array = explode(' - ',input('get.time'));
            $start = strtotime($array[0]." 00:00:00");
            if($array[0] == $array[1]){
                $end = strtotime($array[0]." 23:59:59");
            } else {
                $end = strtotime($array[1]." 00:00:00");
            }
            $where[] = ['order_time','between',[$start,$end]];
        }
        if(!empty($cond['shop_name'])){
            $where[] = ['shop_id','in',function($query) use($cond){
                $query->table('ddt_shops')->where('shop_name','like','%'.$cond['shop_name'].'%')->field('shop_id');
            }];
        }
        $where[] = ['is_del','=',1];
        $with = [
            'getShops' => function($query) {
                $query->field('shop_id,shop_name,shop_phone,imagesurl');
            },
        ];

        $data = $this
            ->field($item)
            ->with($with)
            ->where($where)
            ->paginate($limit);
//        echo $this->getLastSql();
//        var_dump($data);die;
        return $data;
    }

//    获取预定订单详情
    function GetReserveOrderDetail($cond,$item = '*'){

        if(!empty($cond['user_id'])){
            $where[] = ['user_id','=', $cond['user_id']];
        }
        if(isset($cond['shop_id'])){
            $where[] = ['shop_id','=', $cond['shop_id']];
        }
        if(isset($cond['order_id'])){
            $where[] = ['r_o_id','=', $cond['order_id']];
        }
        $where[] = ['is_del','=',1];
        $with = [
            'getShops' => function($query) {
                $query->field('shop_id,shop_name,shop_phone,imagesurl,province,city,area,address,lon,lat');
            },
        ];

        $data = $this
            ->field($item)
            ->with($with)
            ->where($where)
            ->find();
//        echo $this->getLastSql();
//        var_dump($data);die;
        return $data;
    }

    /**
     * 关联建立和shops的关联
     * hasMany方法的参数包括:hasMany('关联模型名','外键名','主键名',['模型别名定义']);
     */
    public function getShops(){
        return $this->hasOne('Shops',"shop_id","shop_id");
    }

//    操作取消订单
    function operatecancelreserve($condition){
        $where[] = ['r_o_id','=',$condition['order_id']];

        if(!empty($condition['user_id'])){
            $where[] = ['user_id', '=', $condition['user_id']];
        }
        $order = $this->getOne($where);
        if(empty($order)){
            $this->setError(-1,'用户不存在该订单');
            return false;
        }
        $order = $order->toArray();
//        var_dump($order);die;
        if($order['order_status'] != 2 || $order['pay_status'] != 2){
            $this->setError(-1,'订单状态有误不允许取消');
            return false;
        }
        $param = [
            'order_status' => 4,
            'pay_status' => 3,
        ];
        $rs = $this->where("r_o_id",'=',$order['r_o_id'])->update($param);
        if($rs === false){
            $this->setError(-1,'操作失败');
            return false;
        }
        return true;
    }
}